﻿using System;
using System.Collections;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using ModbusTCP;

namespace FRS_LIB.Devices
{
    public class CECC : DeviceBase
    {
        private const ushort PORT = 502;
        private const int OUTPUTS = 8;

        Master busclient;

        public CECC(Device device)
            : this(device.Address, device.Name)
        {
        }

        public CECC(string address, string name)
            : base(address, name)
        {
            try
            {
                busclient = new Master(Address, (ushort)PORT, true);
                TcpSendreceive(new byte[] { 2 }, PORT);
            }
            catch (Exception ex)
            {
                busclient = null;
                throw new Exception("The device is not available!", ex);
            } 
            


        }

        protected override byte[] TcpSendreceive(byte[] bytes, int port)
        {
            byte[] result = new byte[32];
            byte[] retVal = new byte[32];
            int startAddress = 2;
            switch (bytes[0])
            {
                // Write output
                case 1:
                    busclient.WriteMultipleRegister(1, 0, 0, new byte[] { 0, bytes[2], 0, bytes[1] }, ref retVal);
                    break;
                // Read outputs
                case 2:
                    busclient.ReadInputRegister(1, 0, 0, 2, ref retVal);
                    break;
                // Read name
                case 4:
                    busclient.ReadInputRegister(1, 0, (ushort)(startAddress + 16 * bytes[1]), 16, ref result);
                    for (int i = 0; i < 16; i++)
                    {
                        retVal[i * 2] = result[i * 2 + 1];
                        retVal[i * 2 + 1] = result[i * 2];
                    }
                    break;
                // Write Name
                case 6:
                    byte[] name = new byte[32];
                    for (int i = 0; i < 16; i++)
                    {
                        name[i * 2] = bytes[i * 2 + 3];
                        name[i * 2 + 1] = bytes[i * 2 + 2];
                    }
                    //Buffer.BlockCopy(bytes, 2, name, 0, name.Length);
                    busclient.WriteMultipleRegister(1, 0, (ushort)(startAddress + bytes[1] * 16), name, ref result);
                    break;
                default:
                    throw new Exception("Wrong Command");
            }
            return retVal;
        }

        public override bool GetOutput(int outputNr)
        {
            Boolean result = false;
            if (outputNr > OUTPUTS-1)
                throw new Exception(String.Format("Device has only {0} ports!", OUTPUTS));

            byte response  = TcpSendreceive(new byte[] { 2 }, PORT)[1];
            BitArray rff = new BitArray(new Byte[] { response });
            foreach(Boolean bit in rff)
            {
                Console.Write(bit?"1":"0");
            }
            Console.WriteLine();
            if ((response & 1<<outputNr) == 1<<outputNr)
            {
                result = true;
            }
            return result;
        }

        public override void SetOutput(int outputNr, int value)
        {
            Console.WriteLine(outputNr + " " + value);
            if (outputNr > OUTPUTS - 1)
                throw new Exception(String.Format("Device has only {0} ports!", OUTPUTS));

            byte[] response = TcpSendreceive(new Byte[] { 1, (byte)(int)Math.Pow(2, outputNr), (byte)(Math.Pow(2, outputNr) * value) }, PORT);
            Console.WriteLine("Answer begin");
            foreach (byte halfW in response)
            {
                BitArray rff = new BitArray(new Byte[] { halfW });
                foreach (Boolean bit in rff)
                {
                    Console.Write(bit ? "1" : "0");
                }
                Console.WriteLine();
            }
            Console.WriteLine("Answer end");
            
            //Console.WriteLine(Encoding.UTF8.GetString(TcpSendreceive(new Byte[] { 1, (byte)(int)Math.Pow(2, outputNr), (byte)(Math.Pow(2, outputNr) * value) }, PORT)));
        }
    }
}
